home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Libris Britannia 4
/
science library(b).zip
/
science library(b)
/
DDJMAG
/
DDJ9310.ZIP
/
1993-OCT.ZIP
/
CAT.ASC
< prev
next >
Wrap
Text File
|
1993-09-17
|
9KB
|
414 lines
_THE C+@ PROGRAMMING LANGUAGE_
by Jim Fleming
[LISTING ONE]
class Clock {
/* An instance of Clock is a window system application
* displaying an analog clock face with Roman Numerals. */
inherit View view;
/* constants */
const minExtent = (96@112);
const font = Font.new(Rroman.8S);
const iconFont = Font.new(Rbold.12S);
/* instance variables */
BlankView analog;
Bitmap icon;
Integer minuteHand;
Integer hourHand;
Point center;
Point minutePoint;
Point hourPoint;
Rectangle dayRectangle;
Process process;
/* CATEGORY: Creation -- Create an instance of a Clock application. */
class method (_) new
{
_ = create;
Layer.new(_);
}
/* RESTRICTED CATEGORY: Initialization -- Initialize an instance of Clock. This
* method is required by View paradigm. It links into view hierarchy by using
* TaViewU as a delegate (of class View). */
method initialize (aView)
{
Point p;
Integer ox, oy, cx, cy;
Integer y;
Rectangle r;
view = aView;
p = view.extent;
if (p.x < minExtent.x || p.y < minExtent.y) {
view.topView.initializeFailed(true);
return;
}
/* Create a BlankView */
ox = 0;
oy = 0;
cx = p.x;
cy = p.y;
r = Rectangle.origin_corner_(ox@oy, cx@cy);
analog = BlankView.basicNew;
thisSelf.newSubView(r, 1, analog);
thisSelf.init;
}
/* RESTRICTED CATEGORY: Window System Event Handling */
/* Receive a window event. If it is a resize event then adjust our subViews. */
method (_) windowEvent(minor, p)
{
Integer ox, oy, cx, cy;
Integer y;
Rectangle r;
if (minor @! Event.WINDOW_RESIZE_EVENT) return;
p = view.extent;
if (p.x < minExtent.x || p.y < minExtent.y) return;
_ = thisSelf;
process.terminate;
ox = 0;
oy = 0;
cx = p.x;
cy = p.y;
r = Rectangle.origin_corner_(ox@oy, cx@cy);
analog.adjustSubView(r);
hourPoint = nil;
minutePoint = nil;
thisSelf.init;
}
method deleteLayerExit
{
process.terminate;
}
/* RESTRICTED CATEGORY: Private -- Initialize an instance of Clock. Draw analog
* clock face and start a surrogate process to update clock time periodically.*/
private init
{
Point p, q;
Integer radius, xor, i, j;
Float sin30, sin60;
Integer n30, n60;
Integer charHeight, charWidth;
/* set up bitmap for clock icon */
icon = Icon_OL.icon(RClockS, R R);
/* set up clock face */
charHeight = font.charHeight(TAU);
charWidth = font.charWidth(TAU);
p = analog.rectangle.extent;
p.y(p.y - 16);
dayRectangle = Rectangle.origin_corner_(0@p.y,analog.rectangle.corner);
if (p.x > p.y)
radius = (p.y / 2) - 2;
else
radius = (p.x / 2) - 2;
center = (p.x / 2)@(p.y / 2);
for (i=0; i < 3; i = i + 1)
analog.circle(center, radius-i, Bitmap.F_STORE);
sin30 = (Float.fromInteger(30) * Float.radiansPerDegree)
.sin;
sin60 = (Float.fromInteger(60) * Float.radiansPerDegree)
.sin;
radius = radius - charHeight*2;
n30 = (sin30 * Float.fromInteger(radius)).asInteger;
n60 = (sin60 * Float.fromInteger(radius)).asInteger;
q = (n30@n60) + center;
thisSelf.centerString(analog, RVS, font, q);
q = (n60@n30) + center;
thisSelf.centerString(analog, RIVS, font, q);
q = (radius@0) + center;
thisSelf.centerString(analog, RIIIS, font, q);
q = (n60@(-n30)) + center;
thisSelf.centerString(analog, RIIS, font, q);
q = (n30@(-n60)) + center;
thisSelf.centerString(analog, RIS, font, q);
q = (0@(-radius)) + center;
thisSelf.centerString(analog, RXIIS, font, q);
q = ((-n30)@(-n60)) + center;
thisSelf.centerString(analog, RXIS, font, q);
q = ((-n60)@(-n30)) + center;
thisSelf.centerString(analog, RXS, font, q);
q = ((-radius)@0) + center;
thisSelf.centerString(analog, RIXS, font, q);
q = ((-n60)@n30) + center;
thisSelf.centerString(analog, RVIIIS, font, q);
q = ((-n30)@n60) + center;
thisSelf.centerString(analog, RVIIS, font, q);
q = (0@radius) + center;
thisSelf.centerString(analog, RVIS, font, q);
j = radius / 20;
for (i=1;i<j;i=i+1)
analog.circle(center, i, Bitmap.F_STORE);
hourHand = radius / 2;
minuteHand = radius * 3 / 4;
/* create clock process */
process = Process.new(thisSelf);
process.clockLoop;
}
method centerString (aView, aString, aFont, aPoint)
{
Integer x,y;
Point p;
x = aFont.xOfString(aString);
y = aFont.yOfString(aString);
p = aPoint - ((x/2)@(y/2));
aView.string(aFont, aString, p, Bitmap.F_STORE);
}
method time (hours, minutes)
{
Integer hq, mq;
Integer length, x, y;
Float hrads, mrads;
String digital;
hours = hours % 12;
if (hours @= 0)
digital = R12S;
else if (hours < 10)
digital = R %S.sprintf(hours);
else
digital = R%S.sprintf(hours);
if (minutes < 10)
digital = digital // R:0%S.sprintf(minutes);
else
digital = digital // R:%S.sprintf(minutes);
Icon_OL.newString(digital, icon);
thisSelf.layer.newIcon(icon);
if (hours < 3)
hq = 1;
else if (hours < 6)
hq = 2;
else if (hours < 9)
hq = 3;
else
hq = 4;
if (minutes < 15)
mq = 1;
else if (minutes < 30)
mq = 2;
else if (minutes < 45)
mq = 3;
else
mq = 4;
hours = (hours % 3) * 60 + minutes;
if (hq @= 2 || hq @= 4) hours = 179 - hours;
minutes = minutes % 15;
if (mq @= 2 || mq @= 4) minutes = 14 - minutes;
hrads = Float.fromInteger(hours/2) * Float.radiansPerDegree;
mrads = Float.fromInteger(minutes*6) * Float.radiansPerDegree;
length = Float.fromInteger(hourHand);
x = (hrads.sin * length).asInteger;
y = (hrads.cos * length).asInteger;
if (hq @= 1)
y = -y;
else if (hq @= 3)
x = -x;
else if (hq @= 4) {
x = -x;
y = -y;
}
analog.batchOn;
if (hourPoint @! nil)
analog.vector(center, hourPoint, Bitmap.F_XOR);
hourPoint = center+(x@y);
analog.vector(center, hourPoint, Bitmap.F_XOR);
length = Float.fromInteger(minuteHand);
x = (mrads.sin * length).asInteger;
y = (mrads.cos * length).asInteger;
if (mq @= 1)
y = -y;
else if (mq @= 3)
x = -x;
else if (mq @= 4) {
x = -x;
y = -y;
}
if (minutePoint @! nil)
analog.vector(center, minutePoint, Bitmap.F_XOR);
minutePoint = center+(x@y);
analog.vector(center, minutePoint, Bitmap.F_XOR);
analog.batchOff;
}
method clockLoop
{
Date time, lastTime;
lastTime = Date.now - 3601*24;
for (;;) {
if (!view.layer.isAlive) {
/* Our layer has been deleted */
Process.running.terminate;
}
time = Date.now;
if (time.minute @! lastTime.minute) {
thisSelf.time(time.hour, time.minute);
if (time.dayOfMonth @! lastTime.dayOfMonth) {
analog.rectf(dayRectangle, Bitmap.F_CLR);
thisSelf.centerString(analog,
time.dayOfWeekString[0,3] << R, R <<
time.monthString <<
R R << time.dayOfMonth.asString,
iconFont, dayRectangle.center);
}
}
lastTime = time;
Timer.sleep(60 - Date.now.second);
}
}
/* end of class Clock */
}
Figure 1:
p=12 @ 34;
Point
x 12
y 34
class Point
{
/* instance variables */
var x; /* x coordinate */
var y; /* y coordinate */
... methods of class Point
}
Figure 2:
p=Rectangle.origin_corner_(12@34,100@200);
Rectangle
origin
corner
Point
x 12
y 34
Point
x 100
y 200
class Rectangle
{
/* instance variables */
var origin;
var corner;
... methods of class Rectangle
}
Figure 3:
(a)
Binary Methods
a=b + c;
p=12 @ 34
Unary/keyword Methods
p=Rectangle.origin_corner_(12@34,100@200);
x=p.origin;
(b)
Binary Methods
a<=b+c
p<=12@34
Keyword Method
p<=Rectangle origin: 12@34 corner: 100@200
Unary Method
x<= p origin
Figure 4:
(a)
if(queue.isEmpty) {
index=0;
}
else{
index=queue.next;
}
(b)
queue isEmpty
ifTrue: [ index <= 0]
ifFalse: [ index <= queue next]
Figure 6:
a_point=Point.x_y_(12,34);
a_point.y_point;
34
Class method
x_y_(12,34)
Point
x 12
y 34
Instance of a Point object
Figure 7:
class Point
{
/* instance variables */
var x; /* x coordinate */
var y; /* y coordinate */
/* class methods */
class method (r) x_y_ (a_x, a_y)
{
/* create an object of class Point and set x=a_x and y=a_y */
r = create;
r.setXY(a_x,a_y);
}
/* instance methods */
private setXY (x_coordinate, y_coordinate)
{
x = x_coordinate;
y = y_coordinate;
}
method (r) x
{
r = x;
}
method (r) x (value)
{
x = value;
r = self;
}
method (r) y
{
r = y;
}
method (r) y (value)
{
y = value;
r = self;
}